/**
* jsgig.res - Functions related to (pre)loading resources.
* 
* Depends: jsgig.event
* 
* There are two event types for this module that are registered when it is
* intialized. They are intended to be used for the purpose of creating in-game 
* loading screens or to otherwise prevent the player from accessing areas of the 
* game before they are loaded. They are described below.
* 
*   {
*     type: "res-preload",
*     resources: [res1, ..., resN]
*   }
*   
* This event is posted once per cycle whenever one or more new resources begin
* to preload. The "resources" paramter is an array of objects being used to
* preload the data, such as HTML images. They are listed in the order that
* they began preloading. Only one event is posted per cycle and it will contain 
* a list of all resources that began preloading in the previous cycle. It is not
* posted if no resources begin preloading.
* 
*   {
*     type: "res-load",
*     resources: [res1, ... resN]
*   }
* 
* This event is posted once all preloading resources have finished loading.
* The "resources" parameter is an array of objects that were used to preload
* the data and will be the same objects that were in the list for the
* "res-preload" event. This event is only posted once _all_ preloading resources
* have loaded and can only occur once per cycle, even if multiple "res-preload"
* events ocurred before it. This means there are not necessarily as many
* "res-load" events as there are "res-preload" events. Stated differently,
* one "res-load" event corresponds to every "res-preload" event that has ocurred
* since the previous "res-load" occurred, if any.
*/
if (!jsgig) {
  throw new Error("jsgig must be included before jsgig.res.");
}
if (!jsgig.res) { jsgig.res = (function () {
var my = {};

var _init = false;
var _loadsPending = [];
var _preloadsSincePost = [];
var _loadsSincePost = [];
var _images = {};

/**
 * Initializes the module.
 * The module may not behave correctly until this is called.
 * It is safe to call this multiple times as only the first call has an effect.
 */
my.init = function init() {
  if (!_init) {
    _init = true;
    if (!jsgig.event)
      throw new Error(
        "jsgig.event is not available. Please be sure that the file " +
        "jsgig/event.js is included."
      );
    jsgig.event.registerType("res-preload", "res-load");
    jsgig.addCycleHook(my.postEvents, jsgig.event.dispatchAll, true);
  }
}

/**
* Begin preloading an image and place the image into the internal image queue.
* An image that is already loaded will not be placed on the queue again.
*/
my.image = function image (src) {
  var img = new Image();
  _loadsPending.push(img);
  _preloadsSincePost.push(img);
  var handleImageLoaded = function handleImageLoaded (e) {
    _loadsPending.splice(_loadsPending.indexOf(img), 1);
    _loadsSincePost.push(img);
    $(img).off({load: handleImageLoaded});
    if (!(img.src in _images))
    _images[src] = img;
  }
  $(img).on({load: handleImageLoaded});
  img.src = src;
}

/**
* Post events to the queue regarding the loading of resources.
* 
* This function is inserted into the game cycle hooks immediately before event
* processing, which allows it to get events onto the queue before events are
* processed for each cycle. Its purpose is to post up to 2 events regarding
* resources that are being or have been loaded since the last cycle completed.
* See the module documentation for details.
*
* This function does not normally need to be called explicitly. 
*/
my.postEvents = function postEvents() {
  var e;
  if (_preloadsSincePost.length) {
    e = new $.Event("res-prelaod");
    e.resources = _preloadsSincePost;
    _preloadsSincePost = [];
    jsgig.event.post(e);
  }
  if (_loadsSincePost.length && !_loadsPending.length) {
    e = new $.Event("res-load");
    e.resources = _loadsSincePost;
    _loadsSincePost = [];
    jsgig.event.post(e);
  }
}

// End of module `jsgig.res`
return my; })(); }